/**
 * 格式化日期
 * @param {Date|number} date 日期
 * @param {string} [format] 格式
 * @return {string}
 */
function formatDate(date, format) {
    if (!format) {
        format = "yyyy-MM-dd HH:mm:ss"
    }
    if (typeof date === "number") {
        date = new Date(date)
    }
    const timeSource = {
        'y': date.getFullYear().toString(), // 年
        'M': (date.getMonth() + 1).toString().padStart(2, '0'), // 月
        'd': date.getDate().toString().padStart(2, '0'), // 日
        'H': date.getHours().toString().padStart(2, '0'), // 时
        'm': date.getMinutes().toString().padStart(2, '0'), // 分
        's': date.getSeconds().toString().padStart(2, '0') // 秒
        // 有其他格式化字符需求可以继续添加，必须转化成字符串
    }
    for (const key in timeSource) {
        const [ret] = new RegExp(`${key}+`).exec(format) || [];
        if (ret) {
            // 年可能只需展示两位
            const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0;
            format = format.replace(ret, timeSource[key].slice(beginIndex));
        }
    }
    return format;
}

/**
 * 构建树形表格
 * @param {string[]} heads 表头标题
 * @param {string[][]} list 数据列表
 * @return {HTMLTableElement}
 */
function buildPropsTable(heads, list) {
    // 构建 table head
    const tableDom = document.createElement('table')
    const theadDom = document.createElement('thead')
    const headTrDom = document.createElement('tr')
    theadDom.appendChild(headTrDom)
    tableDom.appendChild(theadDom)
    const headThList = []
    for (let head of heads) {
        const thDom = document.createElement('th')
        thDom.innerText = head
        headThList.push(thDom)
    }
    headTrDom.append(...headThList)

    // 构建 table body
    const tbodyDom = document.createElement('tbody')
    const bodyTrList = []
    for (let item of list) {
        const trDom = document.createElement('tr')
        const bodyThList = []
        heads.forEach((headItem, index) => {
            const thDom = document.createElement('th')
            thDom.innerHTML = item[index] || '-'
            bodyThList.push(thDom)
        })
        trDom.append(...bodyThList)
        bodyTrList.push(trDom)
    }
    tbodyDom.append(...bodyTrList)
    tableDom.appendChild(tbodyDom)
    return tableDom
}

/**
 * 可选值处理函数
 * @param {string} desc 属性注释
 * @param {string[]} comments 其他行注释
 * @param {string} tsType ts类型
 * @return {string}
 */
function defaultOptionalHandle(desc, comments, tsType) {
    if (tsType) {
        if (typeof tsType === 'string'
            && !tsType.startsWith('Boolean')
            && !tsType.startsWith('Number')
            && !tsType.startsWith('String')
            && !tsType.startsWith('Array')
            && !tsType.startsWith('Object')
            && !tsType.startsWith('~')) {
            // 过滤掉 ts 基础类型和引用类型(~)
            return tsType
        }
    }
    if (comments && comments.length > 0) {
        // 解析注释，将带有 @options 前缀的作为可选值内容
        for (let comment of comments) {
            if (comment.trim().startsWith('@options')) {
                return comment.trim().substring(8)
            }
        }
    }
    return ''
}

/**
 * 解析属性为属性表格需要的列表
 * @param {{[string]:{
 *     type: string,
 *     tsType: string,
 *     default: string,
 *     desc: string,
 *     comments: [],
 *     required: boolean
 * }}} props 属性
 * @return {string[][]}
 */
function relPropsToTableList(props) {
    if (!props) return []
    const tableList = []
    const propKeys = Object.keys(props)
    if (propKeys.length === 0) return []
    for (let propKey of propKeys) {
        const prop = props[propKey]
        const list = []
        list.push([
            propKey,
            prop.required ? '<span class="ex-tag tag-warning tag-mini tag-plain" style="margin-left: 4px">required</span>' : ''
        ].join('\n'))
        list.push(prop.desc)
        list.push(prop.tsType || prop.type)
        list.push(prop.default)
        if (config && config.showOptional) {
            // 可选值处理
            if (config.optionalHandle) {
                list.push(config.optionalHandle(prop.desc, prop.comments, prop.tsType))
            } else {
                list.push(defaultOptionalHandle(prop.desc, prop.comments, prop.tsType))
            }
        }
        tableList.push(list)
    }
    return tableList
}

function relSlotsToTableList(slots) {
    if (!slots || slots.length === 0) return []
    const tableList = []
    for (let slot of slots) {
        const list = []
        list.push(slot.name)
        list.push(slot.desc)
        tableList.push(list)
    }
    return tableList
}

function relEventsToTableList(events) {
    if (!events || events.length === 0) return []
    const tableList = []
    for (let event of events) {
        const list = []
        list.push(event.name)
        list.push(event.desc)
        list.push(event.params)
        tableList.push(list)
    }
    return tableList
}
